package groupd

import (
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
)

var (
	_ GroupAggregateRoot = &groupAggregateRoot{}
)

func initGroup(d ddd.Domain, repo GroupRepo) {
	gar := &groupAggregateRoot{}
	gar.Init(gar, d, DomainID)
	repo.Init(repo, gar, DomainID)

}

// GroupRepo 信息组仓储
type GroupRepo interface {
	ddd.Repository
	// 新增信息组
	AddGroup(ctx ddd.Context, group GroupDesc) (id string, err error)
	// 获取指定信息组：根据唯一标识获取信息组实体
	GetGroup(ctx ddd.Context, groupid string) (*GroupAggregate, error)
	// 分页获取信息组列表：根据唯一标识获取下一页指定数量的信息组实体集合
	// total 总数量
	QueryPage(ctx ddd.Context, s GroupSearch, pi common.PageInfo) (npi common.PageResult, result []GroupAggregate, err error)
	// 修改信息组
	UpdateDesc(ctx ddd.Context, gid string, group GroupDesc) error
	// 修改信息组控制参数
	UpdateCtlParam(ctx ddd.Context, gid string, group GroupCtlParam) error
	// 删除信息组 标记删除
	Delete(ctx ddd.Context, groupid string) error
	// 清空组内所有的信息组
	Empty(ctx ddd.Context, groupid string) error
	// 刷新组内信息组，根据权重重新排序
	Refresh(ctx ddd.Context, groupid string, num int) error
	// 彻底删除指定信息组
	DestroyByID(ctx ddd.Context, groupid string) error
	// 恢复已经删除的指定信息组
	RecoverByID(ctx ddd.Context, groupid string) error
	// 停止收集信息
	StopCollectingByID(ctx ddd.Context, groupid string) error
	// 开始收集信息
	StartCollectingByID(ctx ddd.Context, groupid string) error
	// 按分页查询组内的信息组
	QueryInfoPage(ctx ddd.Context, gid string, pi common.PageInfo) (npi common.PageResult, result []GroupInfoEntity, err error)
	// 查询符合条件的组内的信息
	QueryInfoPageBySch(ctx ddd.Context, sch GroupSearch, pi common.PageInfo) (npi common.PageResult, result []GroupInfoEntity, err error)
	// 向组内追加信息组
	// groupid 指定的组
	// infoid 信息组编号
	// weight 权重值
	// 发出追加信息组事件
	// 如果组正处于刷新状态需要等待刷新完成后再次添加
	AppendInfos(ctx ddd.Context, groupid string, infos []GroupInfoDesc) error
	// DeleteInfo 删除组内信息组
	// infoid 指定要删除的信息组
	DeleteInfos(ctx ddd.Context, groupid string, infoid []string) error
	// DeleteAllInfo 从所有组内删除指定的信息infoid
	// infoid 指定要删除的信息
	DeleteAllInfo(ctx ddd.Context, infoid string) error
	// 加载符合条件的信息组
	// org owner flags 必须指定其中一个条件
	// 返回信息组聚合的数量有限不会无限返回，默认20个
	// org 获取该组织的信息组
	// owner 获取个人的信息组
	// 获取指定标识的信息组，必须标识全部匹配才可以
	LoadGroups(ctx ddd.Context, org string, owner string, flags []string) ([]GroupAggregate, error)

	// ExistNameByDesc 判断name是否存已经存在
	// org 不为空，信息组范围 组织信息组
	// owner 不为空，信息组范围指定所有者的信息组
	// org 和owner都为空 则平台信息组
	// groupid 排除指定的信息组
	// ok true 存在 false 存在
	// err 不等于nil查询失败
	ExistName(ctx ddd.Context, org, owner, groupid, name string) (ok bool, err error)
	// 更新权重值
	UpdateInfoWeight(ctx ddd.Context, giid string, weight int) error

	// 信息编号是否存在组内
	// 返回所有存在组内的id切片
	ExistsForInfo(ctx ddd.Context, groupid string, infoids []string) ([]string, error)
}

// GroupAggregateRoot 信息组的聚合根
type GroupAggregateRoot interface {
	ddd.AggregateRoot
	// 修改信息组中的描述信息组
	// 发出新增信息组事件
	AddGroup(ctx ddd.Context, group GroupDesc) (id string, err error)

	// 获取指定信息组：根据唯一标识获取信息组聚合
	GetGroup(ctx ddd.Context, id string) (ia *GroupAggregate, err error)

	// 分页获取信息组列表：根据唯一标识获取下一页指定数量的信息组实体集合
	// total 总数量
	// is GroupSearch 查询条件
	QueryPage(ctx ddd.Context, is GroupSearch, pi common.PageInfo) (npi common.PageResult, result []GroupAggregate, err error)

	// 加载符合条件的信息组
	// Org Owner  没有设置获取系统的所有信息组
	// 返回信息组聚合的数量有限不会无限返回，默认20个
	// Org 获取该组织的信息组
	// Owner 获取该用户的的信息组
	// Flags 获取指定标识的信息组，必须标识全部匹配才可以
	LoadGroups(ctx ddd.Context, Org string, Owner string, Flags []string) ([]GroupAggregate, error)

	// ExistNameByDesc 判断name是否存已经存在
	// desc Org Owner 为空，信息组范围 平台信息组
	// 		Org Owner 任意不为空，指定组织的信息组或指定所有者的信息组
	// groupid 排除指定的组
	// ok true 存在 false 存在
	// err 不等于nil查询失败
	ExistNameByDesc(ctx ddd.Context, groupid string, desc GroupDesc) (ok bool, err error)
	// // 获取组内信息
	// QueryInfoPage(ctx ddd.Context, gid string, pi common.PageInfo) (npi common.PageResult, result []GroupInfoEntity, err error)

	// // DeleteInfo 删除组内信息组
	// // infoid 指定要删除的信息组
	// // 发出删除信息组事件，删除信息组需要从新调整排序组内数量重新调整
	// DeleteInfos(ctx ddd.Context, groupid string, infoid []string) error

	// 查询符合条件的组内的信息
	QueryInfoPageBySch(ctx ddd.Context, sch GroupSearch, pi common.PageInfo) (npi common.PageResult, result []GroupInfoEntity, err error)
}
type groupAggregateRoot struct {
	ddd.BaseAggregateRoot
}

func (g *groupAggregateRoot) Repo() GroupRepo {
	return g.Repository().(GroupRepo)
}
func (g *groupAggregateRoot) AddGroup(ctx ddd.Context, group GroupDesc) (id string, err error) {
	return g.Repo().AddGroup(ctx, group)
}
func (g *groupAggregateRoot) GetGroup(ctx ddd.Context, id string) (ia *GroupAggregate, err error) {
	return g.Repo().GetGroup(ctx, id)
}

// 分页获取信息组列表：根据唯一标识获取下一页指定数量的信息组实体集合
func (g *groupAggregateRoot) QueryPage(ctx ddd.Context, is GroupSearch, pi common.PageInfo) (npi common.PageResult, result []GroupAggregate, err error) {
	return g.Repo().QueryPage(ctx, is, pi)
}

// func (g *groupAggregateRoot) QueryInfoPage(ctx ddd.Context, gid string, pi common.PageInfo) (npi common.PageResult, result []GroupInfoEntity, err error) {
// 	return g.Repo().QueryInfoPage(ctx, gid, pi)
// }

// 加载符合条件的信息组
// Org Owner Flags 必须指定其中一个条件
// 返回信息组聚合的数量有限不会无限返回，默认20个
// Org 获取改组织的信息组
// Owner 获取个人的信息组
// 获取指定标识的信息组，必须标识全部匹配才可以
func (g *groupAggregateRoot) LoadGroups(ctx ddd.Context, org string, owner string, flags []string) ([]GroupAggregate, error) {
	return g.Repo().LoadGroups(ctx, org, owner, flags)
}

// ExistNameByDesc 判断name是否存已经存在
// desc Org Owner 为空，信息组范围 平台信息组
// 		Org Owner 任意不为空，指定组织的信息组或指定所有者的信息组
// groupid 排除指定的组
// ok true 存在 false 存在
// err 不等于nil查询失败
func (g *groupAggregateRoot) ExistNameByDesc(ctx ddd.Context, groupid string, desc GroupDesc) (ok bool, err error) {
	return g.Repo().ExistName(ctx, desc.Org, desc.Owner, groupid, desc.Name)
}

// 查询符合条件的组内的信息
func (g *groupAggregateRoot) QueryInfoPageBySch(ctx ddd.Context, sch GroupSearch, pi common.PageInfo) (npi common.PageResult, result []GroupInfoEntity, err error) {
	return g.Repo().QueryInfoPageBySch(ctx, sch, pi)
}

// func (g *groupAggregateRoot) DeleteInfos(ctx ddd.Context, groupid string, infoids []string) error {
// 	return g.Repo().DeleteInfos(ctx, groupid, infoids)
// }
